﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Workflow2211A.Application.DTO.Inputs.Workflow;
using Workflow2211A.Application.Services;
using Workflow2211A.Domain;
using Workflow2211A.Domain.Entities;
using WorkflowCore.Interface;
using WorkflowCore.Models;

namespace Workflow2211A.Application.Steps
{
    /// <summary>
    /// 审批步骤
    /// </summary>
    public class AuditStep : StepBody
    {
        private readonly IWorkflowService _workflowService;

        private readonly IWorkflowRegistry _workflowRegistry;

        private readonly IBaseRepository<WorkflowInstanceModel> _instanceRepository;
        public AuditStep(IWorkflowService workflowService, IWorkflowRegistry workflowRegistry, IBaseRepository<WorkflowInstanceModel> instanceRepository)
        {
            _workflowService = workflowService;
            _workflowRegistry = workflowRegistry;
            _instanceRepository = instanceRepository;
        }
        public long AuditUserId { get; set; }
        public string AuditName { get; set; }

        public override ExecutionResult Run(IStepExecutionContext context)
        {
            if (!context.ExecutionPointer.EventPublished)
            {
                Console.WriteLine($"等待{AuditName}审批");
                //添加代办
                _workflowService.AddAudit(new AuditAddInput()
                {
                    AuditUserId = AuditUserId,
                    AuditUserName = AuditName,
                    ExecutionPointerId = context.ExecutionPointer.Id,
                    StepId = context.Step.ExternalId,
                    StepName = context.Step.Name,   
                    WorkflowId = context.Workflow.Id,
                });


                var instance = _instanceRepository.GetAll().FirstOrDefault(x => x.WorkflowId == context.Workflow.Id);
                instance.StepId = context.Step.ExternalId;
                instance.StepName = context.Step.Name;
                instance.Status = "处理中";
                instance.AuditUserId = AuditUserId.ToString();
                instance.AuditUserName = AuditName;
                _instanceRepository.Update(instance);
                return ExecutionResult.WaitForEvent("MyEvent", context.Workflow.Id, DateTime.Now);
            }
            //获取审批数据
            //表示工作流当前执行位置的指针，包含步骤状态和上下文信息。
            //EventData：当工作流通过 WaitForEvent 暂停并等待外部事件时，外部系统触发该事件时可以附带的数据。
            var eventData = context.ExecutionPointer.EventData as AuditInput;
            Console.WriteLine($"{AuditName}审批了，操作类型是：{eventData.OprationType}意见是：{eventData.Remark}");




            //引擎知道步骤执行(从内存中获取)【获取完整的工作流定义】
            var definition =_workflowRegistry.GetDefinition(context.Workflow.WorkflowDefinitionId,context.Workflow.Version);
            //获取结束步骤的执行顺序
            var endStepId = definition.Steps.FirstOrDefault(x=>x.ExternalId == nameof(EndStep))!.Id; 
            //先演示通过，再演示驳回
            if (eventData.OprationType == "驳回")
            {
                //让流程结束
                //Outcomes 就是箭头，代表"下一步去哪里"的路径选择。
                context.Step.Outcomes.Clear();
                context.Step.Outcomes.Add(new ValueOutcome
                {
                    ExternalNextStepId = nameof(EndStep),
                    NextStep = endStepId
                });
                var instance = _instanceRepository.GetAll().FirstOrDefault(x => x.WorkflowId == context.Workflow.Id);
                instance.StepId = context.Step.ExternalId;
                instance.StepName = context.Step.Name;
                instance.Status = "驳回";
                instance.AuditUserId = AuditUserId.ToString();
                instance.AuditUserName = AuditName;
                instance.CompleteTime = DateTime.Now;
                _instanceRepository.Update(instance);
            }
         
            return ExecutionResult.Next();   
            
        }
    }
}
